#ifndef _DSS_COMMON_H
#define _DSS_COMMON_H

#include <stdint.h>


#define HEARTBEAT_INTERVAL (double)5.0 //seconds
/*
* RPC service 
*/
enum
{
    S_CHUNK_IO_SERVICE = 0,
    S_CLIENT_AUTH_SERVICE,
    M_CHUNKOP_SERVICE,
    M_SYSSTATUS_SERVICE,
    M_HEARTBEAT_SERVICE,
		MDS_FILE_OP_SERVICE,
};
/*
* This describe a distrbuted storage system msg header attached to rpc rquest msg header
*/
enum  
{
    CHUNK_OP_CREATE = 0,
    CHUNK_OP_CREATE_REPLY,
    CHUNK_OP_DELETE,
    CHUNK_OP_DELETE_REPLY,
    CHUNK_OP_WRITE,
    CHUNK_OP_WRITE_REPLY,
    CHUNK_OP_READ,
    CHUNK_OP_READ_REPLY,
    CHUNK_OP_LIST,
    CHUNK_OP_LIST_REPLY,
    CS_HEARTBEAT,
    CS_HEARTBEAT_REPLY,
    SYS_STATUS,
    SYS_STATUS_REPLY,

};
/*
* op *<-> chunkserver response status
*/
enum
{
    SUCCESS = 0,
    FAILURE,
    BLOBSTORE_ERROR, // error happen in blobstore
    UNSUPPORTED_TYPE,  // message type is not supported
    INEXISTENT_CHUNK, // chunk id is not found in chunkserver
};

struct chunk_id {
    uint64_t cs_id;
    uint64_t blob_id;
};

/*
* dss request 
*/

/*request for chunk operations*/


struct chunk_req {
    struct chunk_id id;
    uint32_t chunk_len;
    uint32_t chunk_off;
    uint32_t data_len; //data inline (< 4KB)
    char data[0];
};


struct heartbeat_req {
    uint64_t cs_id;
    uint32_t cluster_total; //the number of total clusters in blobstore
    uint32_t cluster_free; // the number of free clusters in blobstore
    uint32_t cluster_size; // the size of a cluster, usually 1MB
    uint32_t io_unit_size; // read or write minimum size, usually 4KB
};

struct status_req {

};

/*
* dss response
*/
struct chunk_resp {
    struct chunk_id id;
    uint32_t data_len; //data inline(<4KB)
    char data[0];
};

struct heartbeat_resp {

};

struct status_resp {

};


struct dss_msg
{
    union {
        uint16_t client_id; //for request, who send request? 
        uint16_t status_code; //for response 
    };
    uint16_t msg_type;
    uint32_t msg_id;
    
    uint32_t data_len;
    char  data[0];
};

/* Example : client send request header to delete chunk
void client_delete_chunk(struct rpc* self, struct chunk_id* id, uint32_t sess_id) {
    struct msg_base* rpc_header = alloc_msg_header(self);

    prepare_msg_header(rpc_header, C_CHUNK_IO_SERVICE, 0, 0, 0, 0, sizeof(struct dss_msg)+sizeof(struct chunk_req));

    struct dss_msg* dss_header = (struct dss_msg*)rpc_header->data;
    dss_header->client_id = -1;
    dss_header->msg_id = cur_id++;
    dss_header->msg_type = CHUNK_OP_DELETE;
    
    struct chunk_req* chunk_op_header = (struct chunk_req*)dss_header->header;
    chunk_op_header->id.blob_id = id->blob_id;
    chunk_op_header->id.cs_id = id->cs_id;
    chunk_op_header->data_len = 0;

    dss_header->header_len = sizeof(struct chunk_req) + chunk_op_header->data_len;
    enqueue_request(self, sess_id, rpc_header, cb, cb_arg,0);
}
*/
#endif // !_DSS_COMMON_H
